#ifndef _H_SMARTKB_H_
#define _H_SMARTKB_H_

#include "CommCtrl.h"

class SmartKBListCtrl;

class SmartKBEditCtrl : public UIXWnd2Impl<SmartKBEditCtrl,UIEdit2>
{
	typedef SmartKBEditCtrl This;
	typedef UIXWnd2Impl<SmartKBEditCtrl,UIEdit2> Base;
protected:
	SmartKBListCtrl* m_pList;
public:
	SmartKBEditCtrl();

	void SetList(SmartKBListCtrl* pList);

	BEGIN_MSG_MAP(This)
		MESSAGE_HANDLER(WM_KEYDOWN, OnKeyDown)
		MESSAGE_HANDLER(WM_CHAR, OnChar)
		CHAIN_MSG_MAP(Base)
	END_MSG_MAP()

	LRESULT OnKeyDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnChar(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

};

class SmartKBListCtrl 
	: public WndObjecterImpl<SmartKBListCtrl,UIListCtrl2>
	, public MyListCtrlMap<SmartKBListCtrl>
	, public UIPaint<SmartKBListCtrl>
{
	typedef SmartKBListCtrl This;
	typedef WndObjecterImpl<SmartKBListCtrl,UIListCtrl2> Base;
	typedef MyListCtrlMap<SmartKBListCtrl> ListCtrlMap;
	typedef UIPaint<SmartKBListCtrl> PaintMap;
	DECLARE_XMLWND_CLASS(_T("SmartKBList"))
	DECLARE_DYNCREATE_WND_OBJECTER(SmartKBListCtrl,Objecter)
public:
	SmartKBListCtrl();
	virtual ~SmartKBListCtrl();

	//BOOL IsDirectUI() { return TRUE; }

	HWND Create(HWND hWndParent, RECT& rcPos
		, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL);
	HWND Create(HWND hWndParent, LPCTSTR lpszXml = NULL, UINT XmlFlag = XML_FLAG_FILE);

	void Relayout(LPCRECT lpRect = NULL);

	COLORREF GetBkColor();
	BOOL SetBkColor(COLORREF cr);

	void OnGetDispInfo(NMLVDISPINFO* lpDispInfo);
	void OnPaint(HDC hdc);

	BEGIN_MSG_MAP(This)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(LVM_GETBKCOLOR, OnGetBkColor)
		MESSAGE_HANDLER(LVM_SETBKCOLOR, OnSetBkColor)
		CHAIN_MSG_MAP(ListCtrlMap)
		//CHAIN_MSG_MAP(PaintMap)
		CHAIN_MSG_MAP(Base)
		DEFAULT_REFLECTION_HANDLER()
	END_MSG_MAP()

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnGetBkColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnSetBkColor(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

protected:
	void InitColList();

protected:
	std::vector<SmartKBObjectPtr> m_SmartKBPtrList;

public:

	BEGIN_EVT_MAP(This)
		ON_EVT(EVT_PLAT_CALL,OnCall)
		CHAIN_EVT_MAP(Base)
	END_EVT_MAP()

	long OnCall(Event& evt);
};

class SmartKBComboBox 
	: public WndObjecterImpl<SmartKBComboBox>
	, public UIPaint<SmartKBComboBox>
	, public UIOwnerDraw<SmartKBComboBox>
	, public MyListCtrlMap<SmartKBComboBox>
	, public AsyncWndFinder<SmartKBComboBox>
{
	typedef SmartKBComboBox This;
	typedef WndObjecterImpl<SmartKBComboBox> Base;
	typedef UIPaint<SmartKBComboBox> Paint;
	typedef UIOwnerDraw<SmartKBComboBox> OwnerDraw;
	typedef AsyncWndFinder<SmartKBComboBox> AsyncFinder;
	DECLARE_XMLWND_CLASS(_T("SmartKBComboBox"))
	DECLARE_DYNCREATE_WND_OBJECTER(SmartKBComboBox,Objecter)
protected:
	SmartKBEditCtrl m_input;
	SmartKBListCtrl m_list;
	UINT m_uTimer;
public:
	SmartKBComboBox();
	virtual ~SmartKBComboBox();

	HWND Create(HWND hWndParent, RECT& rcPos
		, LPCTSTR szWindowName = NULL, DWORD dwStyle = 0, DWORD dwExStyle = 0, UINT nID = 0, LPVOID lpCreateParam = NULL);
	HWND Create(HWND hWndParent, LPCTSTR lpszXml = NULL, UINT XmlFlag = XML_FLAG_FILE);

	HWND GetEditCtrl();
	HWND GetListCtrl();

	void Relayout(LPCRECT lpRect = NULL);
	void ShowDropDown(BOOL bShow = TRUE);

	BOOL PreTranslateMessage(MSG* pMsg);

	void OnPaint(HDC hdc);
	HBRUSH OnCtlColor(HDC hdc, HWND hWnd, UINT nCtlColor);

	BEGIN_MSG_MAP_EX(This)
		MESSAGE_HANDLER(WM_CREATE, OnCreate)
		MESSAGE_HANDLER(WM_DESTROY, OnDestroy)
		MESSAGE_HANDLER(WM_SIZE, OnSize)
		MESSAGE_HANDLER(WM_TIMER, OnTimer);
		MESSAGE_HANDLER(WM_LBUTTONDOWN, OnLButtonDown)
		COMMAND_CODE_HANDLER(EN_SETFOCUS, OnEnSetFocus)
		COMMAND_CODE_HANDLER(EN_KILLFOCUS, OnEnKillFocus)
		COMMAND_CODE_HANDLER(EN_UPDATE, OnEnUpdate)
		MESSAGE_HANDLER(WM_USER, OnFindComplete)
		CHAIN_MSG_MAP(Paint)
		CHAIN_MSG_MAP(OwnerDraw)
		CHAIN_MSG_MAP(Base)
		REFLECT_NOTIFICATIONS()
	END_MSG_MAP()

	LRESULT OnCreate(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnDestroy(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnSize(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnTimer(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnLButtonDown(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);
	LRESULT OnEnSetFocus(int wNotifyCode, int wID, HWND hwndCtl, BOOL& bHandled);
	LRESULT OnEnKillFocus(int wNotifyCode, int wID, HWND hwndCtl, BOOL& bHandled);
	LRESULT OnEnUpdate(int wNotifyCode, int wID, HWND hwndCtl, BOOL& bHandled);
	LRESULT OnFindComplete(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled);

protected:
	CString m_strInput;
	SmartKBInfoPtr m_InfoPtr;

public:
	virtual void OnIdle();
	virtual long OnFind();

public:
	void OnDispInfoChanged();
};

#endif//_H_SMARTKB_H_
